//
// Created by maohuan on 2022/12/1.
//

#include "SQLiteHelper.h"
#include "sqlite3.h"

SQLiteHelper::SQLiteHelper()
{
    m_db = NULL;
}

SQLiteHelper::~SQLiteHelper()
{
    closeDB();
}

SQLiteHelper& SQLiteHelper::instance(){
    static SQLiteHelper m_instance;
    return m_instance;
}

bool SQLiteHelper::execSQL(const char* sql)
{
    if(!m_db) return false;
    char* cErrMsg = NULL;
    int nResult = sqlite3_exec(m_db, sql, 0, 0, &cErrMsg);
    if (nResult != SQLITE_OK){
        sqlite3_free(cErrMsg);
        return false;
    }
    return true;
}

int SQLiteHelper::numRows(const char* sql)
{
    if(!m_db) return 0;

    char* cErrMsg = NULL;
    char** pResult = NULL;
    int nRow = 0, nCol = 0;

    std::unique_lock<std::mutex> lk(m_event_mutex);

    int nResult = sqlite3_get_table(m_db, sql, &pResult, &nRow, &nCol, &cErrMsg);
    if (nResult != SQLITE_OK){
        sqlite3_free(cErrMsg);
        return 0;
    }
    sqlite3_free_table(pResult);
    return nRow;
}

int SQLiteHelper::rawQuery(const char* sql, std::vector<std::map<std::string, std::string> >& mapValue)
{
    if(!m_db) return 0;

    char* cErrMsg = NULL;
    char** pResult = NULL;
    int nRow = 0,nCol = 0;

    int nResult = sqlite3_get_table(m_db, sql, &pResult, &nRow, &nCol, &cErrMsg);
    if (nResult != SQLITE_OK){
        sqlite3_free(cErrMsg);
        return 0;
    }
    /**
    dbResult[n]   [n+1]  [n+2]  [n+3].....[n+n-1] (dbResult[n]~[n+n-1]分别代表第一条记录的值)

    dbResult[2n]  [2n+1] [2n+2] [2n+3]....[2n+n-1](dbResult[2n]~[2n+n-1]分别代表第二条记录的值)

    dbResult[3n]  [3n+1] [3n+2] 32n+3]....[3n+n-1](dbResult[3n]~[3n+n-1]分别代表第三条记录的值)
   **/

    std::string strOut;
    int nIndex = nCol;
    for (int i = 0; i < nRow; i++)
    {
        std::map<std::string, std::string> resultMap;
        for (int j = 0; j < nCol; j++){
            const char *key = pResult[j];
            const char *value = pResult[nIndex];
            if(key == nullptr) continue;
            resultMap[key] = (value == nullptr)? "": value;
            ++nIndex;
        }
        mapValue.push_back(resultMap);
    }
    sqlite3_free_table(pResult);

    return 0;
}

int SQLiteHelper::rawQuery(const char* sql, std::map<std::string, std::string>* mapValue,int max_platform_num)
{
    if(!m_db) return 0;

    char* cErrMsg = NULL;
    char** pResult = NULL;
    int nRow = 0,nCol = 0;

    int nResult = sqlite3_get_table(m_db, sql, &pResult, &nRow, &nCol, &cErrMsg);
    if (nResult != SQLITE_OK){
        sqlite3_free(cErrMsg);
        return -1;
    }


    int nIndex = nCol;
    std::string strOut;

    if (nRow > max_platform_num) {
        nRow = max_platform_num;
    }

    for (int i = 0; i < nRow; i++){
        for (int j = 0; j < nCol; j++){
            const char *key = pResult[j];
            const char *value = pResult[nIndex];
            if(key == nullptr) continue;

            mapValue[i][key] = (value == nullptr)?"":value;
            //mapValue[pResult[j]] = pResult[nIndex];
            ++nIndex;
        }
    }

    sqlite3_free_table(pResult);

    return 0;
}

int SQLiteHelper::rawQuery(const char* sql, std::map<std::string, std::string>& mapValue)
{
    if(!m_db) return -1;

    char* cErrMsg = NULL;
    char** pResult = NULL;
    int nRow = 0,nCol = 0;

    int nResult = sqlite3_get_table(m_db, sql, &pResult, &nRow, &nCol, &cErrMsg);
    if (nResult != SQLITE_OK){
        sqlite3_free(cErrMsg);
        return -1;
    }

    std::string strOut;
    int nIndex = nCol;
    for (int i = 0; i < nRow; i++){
        for (int j = 0; j < nCol; j++){
            const char *key = pResult[j];
            const char *value = pResult[nIndex];
            if(key == nullptr) continue;
            mapValue[key] = (value == nullptr)?"":value;
            ++nIndex;
        }
    }

    sqlite3_free_table(pResult);

    return 0;
}

bool SQLiteHelper::openDB(const char* path)
{
    int last = sqlite3_open(path, &m_db);
    if (SQLITE_OK != last){
        return false;
    }
    return true;
}

void SQLiteHelper::closeDB()
{
    if(!m_db) return;
    sqlite3_close(m_db);
}
